home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
os2
/
vsoup11.zip
/
kill.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-02
|
6KB
|
296 lines
// $Id: kill.cc 1.9 1996/09/02 13:22:34 hardy Exp $
//
// This progam/module was written by Hardy Griech based on ideas and
// pieces of code from Chin Huang (cthuang@io.org). Bug reports should
// be submitted to rgriech@ibm.net.
//
// This file is part of soup++ for OS/2. Soup++ including this file
// is freeware. There is no warranty of any kind implied. The terms
// of the GNU Gernal Public Licence are valid for this piece of software.
//
// Kill file processing
//
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <regexp.h>
#include "kill.hh"
#include "mts.hh"
TKillFile::TKillFile( void )
{
globalKill = groupKillList = cacheGroupKill = NULL;
cacheGroupName = xstrdup("");
} // TKillFile::TKillFile
void TKillFile::killGroup( Group *gp )
{
Exp *ep1, *ep2;
if (gp == NULL)
return;
ep1 = gp->expList;
while (ep1 != NULL) {
if (ep1->re != NULL) {
//// delete ep1->re;
}
ep2 = ep1->next;
//// delete ep1;
ep1 = ep2;
}
//// delete gp->name;
//// delete gp;
} // TKillFile::killGroup
TKillFile::~TKillFile()
{
Group *gp1, *gp2;
//// delete cacheGroupName;
killGroup( globalKill );
gp1 = groupKillList;
while (gp1 != NULL) {
gp2 = gp1->next;
killGroup( gp1 );
gp1 = gp2;
}
} // TKillFile::~TKillFile
TKillFile::Exp *TKillFile::readExp(const char *searchIn, const char *searchFor)
{
char exp[BUFSIZ];
Exp *result;
if (searchFor[0] == '\0')
return NULL;
if (stricmp(searchIn, "header") == 0) {
strcpy(exp, searchFor);
} else {
strcpy( exp, "^" );
strcat( exp, searchIn );
strcat( exp, ":.*" );
strcat( exp, searchFor );
}
result = new Exp;
result->next = NULL;
strlwr(exp);
result->re = regcompT(exp);
return result;
} // TKillFile::readExp
int TKillFile::readFile( const char *killFile, int maxLines )
//
// Read kill file and compile regular expressions.
// Return: -1 -> file not found, 0 -> syntax error, 1 -> ok
// Nicht so hanz das optimale: besser wäre es eine Zustandsmaschine
// zusammenzubasteln...
//
{
char buf[BUFSIZ], name[FILENAME_MAX];
char searchIn[BUFSIZ], searchFor[BUFSIZ];
FILE *inf;
Group *pGroup, *pLastGroup;
Exp *pExp, *pLastExp;
char ok;
globalKill = groupKillList = NULL;
TKillFile::maxLines = maxLines;
if ((inf = fopenT(killFile, "r")) == NULL) {
return -1;
}
sema.Request();
pLastGroup = NULL;
ok = 1;
//
// read newsgroup name
//
while (ok && fscanfT(inf, "%s%*[ \t\n]%[^\n]\n", name,buf) == 2) {
#ifdef DEBUG_ALL
printfT( "name: '%s', '%s'\n",name,buf );
#endif
if (name[0] == '#') // comment
continue;
if (buf[0] != '{' || buf[1] != '\0') {
ok = 0;
break;
}
if (stricmp(name, "all") == 0) {
//
// Allocate global kill entry.
//
if (globalKill == NULL) {
globalKill = new Group;
globalKill->name = NULL;
globalKill->expList = NULL;
}
pGroup = globalKill;
} else {
//
// Allocate group kill entry.
//
pGroup = new Group;
pGroup->expList = NULL;
pGroup->name = xstrdup(name);
pGroup->next = NULL;
if (pLastGroup == NULL)
groupKillList = pGroup;
else
pLastGroup->next = pGroup;
pLastGroup = pGroup;
}
pGroup->expList = NULL;
//
// Read kill expressions until closing brace.
//
pLastExp = NULL;
while (fscanfT(inf, "%s%*[ \t]%[^\n]\n", searchIn,searchFor) != -1) {
while (searchFor[0] != '\0' && isspace(searchFor[strlen(searchFor)-1]))
searchFor[strlen(searchFor)-1] = '\0';
#ifdef DEBUG_ALL
printfT( "search: '%s', '%s'\n",searchIn,searchFor );
#endif
if (searchIn[0] == '#') // comment
continue;
if (searchIn[0] == '}' && searchIn[1] == '\0')
break;
if ((pExp = readExp(searchIn,searchFor)) == NULL) {
ok = 0;
break;
}
if (pLastExp == NULL)
pGroup->expList = pExp;
else
pLastExp->next = pExp;
pLastExp = pExp;
}
}
sema.Release();
fcloseT(inf);
if (!ok)
fprintfT(stderr, "error in kill file %s,\n\tsection %s\n", killFile,name);
return ok;
} // TKillFile::readFile
TKillFile::Group *TKillFile::getGroupP( const char *groupName )
//
// return group kill for *groupName
//
{
Group *p;
Group *res;
#ifdef TRACE_ALL
// printfT( "TKillFile::getGroupP(%s)\n",groupName );
#endif
sema.Request();
if (stricmp(groupName,cacheGroupName) != 0) {
for (p = groupKillList; p != NULL; p = p->next) {
if (stricmp(p->name, groupName) == 0) {
xstrdup( &cacheGroupName, p->name );
cacheGroupKill = p;
break;
}
}
if (p == NULL) {
xstrdup( &cacheGroupName, "" );
cacheGroupKill = NULL;
}
}
res = cacheGroupKill;
sema.Release();
return res;
} // TKillFile::getGroupP
int TKillFile::matchExp(Group *pGroup, const char *buf)
{
Exp *pExp;
if (pGroup == NULL)
return 0;
sema.Request();
for (pExp = pGroup->expList; pExp != NULL; pExp = pExp->next) {
if (regexecT(pExp->re, buf)) {
sema.Release();
return 1;
}
}
sema.Release();
return 0;
} // TKillFile::matchExp
int TKillFile::matchLine( const char *groupName, const char *line )
//
// Check if line matches kill criteria.
// Return TRUE if article should be killed.
//
{
char *buf;
int match = 0;
//
// remove trailing '\n' and make lower cases
//
buf = (char *)xstrdup( line );
strlwr(buf);
//
// article too long ?
//
if (maxLines > 0 && strncmp(buf, "lines: ", 7) == 0) {
match = (atoi(buf+7) > maxLines);
}
if ( !match) {
//
// is there any match with the killFile ?
//
match = matchExp(globalKill, buf) || matchExp(getGroupP(groupName), buf);
}
delete buf;
return match;
} // TKillFile::matchLine
int TKillFile::doKillQ( const char *groupName )
{
return maxLines > 0 || globalKill != NULL || getGroupP(groupName) != NULL;
} // doKillQ